package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.MyCollectionCountVO;
import com.sc.nft.entity.vo.merchantPledgeTask.AdminEcologyIncomeConfListVO;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.helper.MessageQueueHelper;
import com.sc.nft.service.EcologyHatchScriptService;
import com.sc.nft.service.UserEcologyPointsService;
import com.sc.nft.util.BigDecimalUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author：LiGen
 * @Package：com.sc.nft.service.impl
 * @Project：sc_metago
 * @name：EcologyHatchScriptServiceImpl
 * @Date：2024/6/20 13:47
 * @Filename：EcologyHatchScriptServiceImpl
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EcologyHatchScriptServiceImpl implements EcologyHatchScriptService {

    /**
     * 熔炼配置
     */
    private final EcologyHatchConfDao ecologyHatchConfDao;
    /**
     * 熔炼奖励配置
     */
    private final EcologyHatchRewardsConfDao ecologyHatchRewardsConfDao;

    /**
     * 熔炼的铸造配置
     */
    private final EcologyCastConfDao ecologyCastConfDao;

    /**
     * 熔炼上限记录表
     */
    private final UserEcologyCastUpperLimitDetailsDao userEcologyCastUpperLimitDetailsDao;

    /**
     * 重铸上限记录表
     */
    private final UserEcologyReforgeUpperLimitDetailsDao userEcologyReforgeUpperLimitDetailsDao;
    /**
     * 铸造消耗的道具配置
     */
    private final EcologyCastExpendConfDao ecologyCastExpendConfDao;

    /**
     * 用户熔炼记录
     */
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;

    /**
     * 熔炼消耗藏品数量记录表
     */
    private final UserEcologyCollectionRecordsDao userEcologyCollectionRecordsDao;

    /**
     * 用户-生态-孵化-藏品记录
     */
    private final UserEcologyHatchCollectionRecordsDao userEcologyHatchCollectionRecordsDao;

    /**
     * 用户铸造上限
     */
    private final UserEcologyCastUpperLimitDao userEcologyCastUpperLimitDao;

    /**
     * 用户重铸上限
     */
    private final UserEcologyReforgeUpperLimitDao userEcologyReforgeUpperLimitDao;

    private final MessageQueueHelper messageQueueHelper;

    private final EcologyHatchRecordsRewardsDao ecologyHatchRecordsRewardsDao;

    private final EcologyHatchMethodConfDao ecologyHatchMethodConfDao;

    private final EcologyHatchMethodCollectionConfDao ecologyHatchMethodCollectionConfDao;

    private final UserEcologyPointsQuotaRecordsDao userEcologyPointsQuotaRecordsDao;

    private final UserEcologyPointsService userEcologyPointsService;

    /**
     * 生态熔炼初始化配置
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initialConfigurationOfEcologicalMelting(Long id) {
        // 查询出没有关联熔炼方式的生态熔炼配置
        List<EcologyHatchConf> scriptNeedList = ecologyHatchConfDao.getScriptNeedList(id);
        // 遍历生态熔炼配置
        for (EcologyHatchConf ecologyHatchConf : scriptNeedList) {
            // 熔炼方法配置
            EcologyHatchMethodConf ecologyHatchMethodConf = new EcologyHatchMethodConf();
            ecologyHatchMethodConf.setEcologyHatchId(ecologyHatchConf.getId());
            ecologyHatchMethodConf.setSort(0L);
            ecologyHatchMethodConf.setStatus(Boolean.TRUE);
            ecologyHatchMethodConf.insert();
            // 熔炼记录消耗对应的藏品以及数量初始化
            quantityInitialization(ecologyHatchConf, ecologyHatchMethodConf.getId());
            // 绑定熔炼方法配置奖励
            ecologyHatchRewardsConfDao.updateMethodId(ecologyHatchMethodConf.getEcologyHatchId(), ecologyHatchMethodConf.getId());
            // 修改熔炼配置中需要小号的藏品
            Integer expendCount = ecologyHatchConf.getExpendCount();
            ecologyHatchConf.setExpendCount(expendCount - 1);
            ecologyHatchConfDao.updateById(ecologyHatchConf);
            // 新增熔炼方法藏品配置
            EcologyHatchMethodCollectionConf ecologyHatchMethodCollectionConf = new EcologyHatchMethodCollectionConf();
            ecologyHatchMethodCollectionConf.setCollectionId(ecologyHatchConf.getCollectionId());
            ecologyHatchMethodCollectionConf.setMethodId(ecologyHatchMethodConf.getId());
            ecologyHatchMethodCollectionConf.setEcologyHatchId(ecologyHatchMethodConf.getEcologyHatchId());
            ecologyHatchMethodCollectionConf.setCollectionId(ecologyHatchConf.getCollectionId());
            ecologyHatchMethodCollectionConf.setCollectionName(ecologyHatchConf.getCollectionName());
            ecologyHatchMethodCollectionConf.setExpendCount(1);
            ecologyHatchMethodCollectionConf.setDestroyCount(0);
            ecologyHatchMethodCollectionConf.insert();

        }
    }

    /**
     * 生态铸造上限以及重铸上限以及兑换上限初始化
     */
    @Override
    public void upperLimitInitialization(EcologyHatchConf ecologyHatchConf, Map<Long, List<UserEcologyHatchRecords>> userEcologyHatchRecordsMap) {
        // 获取熔炼配置的铸造配置以及藏品配置
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getOneByCollectionId(ecologyHatchConf.getCollectionId());
        // 获取熔炼配置下的权益道具奖励
        EcologyHatchRewardsConf ecologyHatchRewardsConf = ecologyHatchRewardsConfDao.getByEcologyHatchId(ecologyHatchConf.getId(), EcologyRewardsType.EQUITY_PROPS);
        // 获取铸造配置消耗的道具
        EcologyCastExpendConf ecologyCastExpendConf = ecologyCastExpendConfDao.getListByCastId(ecologyCastConf.getId());
        // 遍历用户熔炼记录
        List<UserEcologyReforgeUpperLimit> userEcologyReforgeUpperLimitList = new ArrayList<>();
        // 铸造上限记录明细表
        List<UserEcologyCastUpperLimitDetails> userEcologyCastUpperLimitDetailsList = new ArrayList<>();
        // 重铸上限记录明细表
        List<UserEcologyReforgeUpperLimitDetails> userEcologyReforgeUpperLimitDetailsList = new ArrayList<>();
        List<TemporarilyDTO> temporarilyDTOList = new ArrayList<>();
        for (Long userId : userEcologyHatchRecordsMap.keySet()) {
            // 获取用铸造上限
            UserEcologyCastUpperLimit userEcologyCastUpperLimit = userEcologyCastUpperLimitDao.getOneByUserIdAndCollectionId(userId, ecologyHatchConf.getCollectionId());
            // 总出券数量
            BigDecimal totalNumberOfVouchersIssued = BigDecimal.ZERO;
            List<UserEcologyHatchRecords> userEcologyHatchRecords = userEcologyHatchRecordsMap.get(userId);
            for (UserEcologyHatchRecords userEcologyHatchRecord : userEcologyHatchRecords) {
                // 剩余天数
                int remainingDays = userEcologyHatchRecord.getHatchCycle() - userEcologyHatchRecord.getAlreadyDay();
                // 出券数量
                BigDecimal num = BigDecimalUtils.multiplys(0, RoundingMode.FLOOR, BigDecimalUtils.divide(remainingDays, ecologyHatchRewardsConf.getRewardsCycle(), 0, RoundingMode.CEILING), ecologyHatchRewardsConf.getLinkCount(), userEcologyHatchRecord.getHatchCount());

                totalNumberOfVouchersIssued = BigDecimalUtils.add(totalNumberOfVouchersIssued, num);
            }
            // 用户熔炼剩余可产出的藏品数
            Integer userSurplusCount = BigDecimalUtils.divide(totalNumberOfVouchersIssued, ecologyCastExpendConf.getExpendCount(), 0, RoundingMode.CEILING).intValue();
            if (BigDecimalUtils.multiplys(userSurplusCount, ecologyCastExpendConf.getExpendCount()).intValue() > totalNumberOfVouchersIssued.intValue()) {
                // 产出数量单数 向上取整的
                TemporarilyDTO temporarilyDTO = new TemporarilyDTO();
                temporarilyDTO.setUserId(userId);
                temporarilyDTO.setEcologyHatchId(ecologyHatchConf.getId());
                temporarilyDTO.setCollectionName(ecologyHatchConf.getCollectionName());
                temporarilyDTOList.add(temporarilyDTO);
            }
            // 可兑换数量
            Integer exchangeCount = 0;
            // 铸造数量
            Integer castCount = 0;
            // 重铸数量
            Integer reforgeCount = 0;
            if (userSurplusCount >= userEcologyCastUpperLimit.getUsableCount()) {
                // 熔炼待产出的藏品数量 ≥ 用户当前铸造上限，生态铸造上限 = 用户当前铸造上限 ，生态铸造可兑换次数 = 熔炼待产出的藏品数量 - 用户当前铸造上限，重铸上限为0
                exchangeCount = userSurplusCount - userEcologyCastUpperLimit.getUsableCount();
                castCount = userEcologyCastUpperLimit.getUsableCount();
            } else {
                // 熔炼待产出的藏品数量 ＜ 用户当前铸造上限，生态铸造上限重置为熔炼待产出的藏品数量，生态铸造可兑换次数 = 0 ，重铸上限 = 用户当前铸造上限 - 熔炼待产出的藏品数量
                castCount = userSurplusCount;
                reforgeCount = userEcologyCastUpperLimit.getUsableCount() - userSurplusCount;
            }
            if (userEcologyCastUpperLimit.getUsableCount() > castCount) {
                // 铸造上限调整记录
                UserEcologyCastUpperLimitDetails userEcologyCastUpperLimitDetails = new UserEcologyCastUpperLimitDetails();
                userEcologyCastUpperLimitDetails.setUserId(userId);
                userEcologyCastUpperLimitDetails.setCollectionId(ecologyHatchConf.getCollectionId());
                userEcologyCastUpperLimitDetails.setUserRecordsId(0L);
                userEcologyCastUpperLimitDetails.setType(UserEcologyCastUpperLimitDetailsTypeEnum.SYS);
                userEcologyCastUpperLimitDetails.setTypeName(UserEcologyCastUpperLimitDetailsTypeEnum.SYS.getDescription());
                userEcologyCastUpperLimitDetails.setUseCount(userEcologyCastUpperLimit.getUsableCount() - castCount);
                userEcologyCastUpperLimitDetails.setBeforeCount(userEcologyCastUpperLimit.getUsableCount());
                userEcologyCastUpperLimitDetails.setAfterCount(castCount);
                userEcologyCastUpperLimitDetails.setIsAdd(UserEcologyCastUpperLimitDetailsTypeEnum.SYS.getIsAdd());
                userEcologyCastUpperLimitDetailsList.add(userEcologyCastUpperLimitDetails);
            }

            if (reforgeCount > 0) {
                // 重铸上限调整记录
                UserEcologyReforgeUpperLimitDetails userEcologyReforgeUpperLimitDetails = new UserEcologyReforgeUpperLimitDetails();
                userEcologyReforgeUpperLimitDetails.setUserId(userId);
                userEcologyReforgeUpperLimitDetails.setCollectionId(ecologyHatchConf.getCollectionId());
                userEcologyReforgeUpperLimitDetails.setUserRecordsId(0L);
                userEcologyReforgeUpperLimitDetails.setType(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS);
                userEcologyReforgeUpperLimitDetails.setTypeName(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS.getDescription());
                userEcologyReforgeUpperLimitDetails.setUseCount(reforgeCount);
                userEcologyReforgeUpperLimitDetails.setBeforeCount(0);
                userEcologyReforgeUpperLimitDetails.setAfterCount(reforgeCount);
                userEcologyReforgeUpperLimitDetails.setIsAdd(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS.getIsAdd());
                userEcologyReforgeUpperLimitDetailsList.add(userEcologyReforgeUpperLimitDetails);
            }
            userEcologyCastUpperLimit.setUsableCount(castCount);
            userEcologyCastUpperLimit.setExchangeCount(exchangeCount);
            Assert.isTrue(userEcologyCastUpperLimit.updateById(),
                    () -> new GlobalRunTimeException("用户铸造上限更新失败,铸造上限ID:{}" + userEcologyCastUpperLimit.getId()));
            UserEcologyReforgeUpperLimit userEcologyReforgeUpperLimit = new UserEcologyReforgeUpperLimit();
            userEcologyReforgeUpperLimit.setUserId(userId);
            userEcologyReforgeUpperLimit.setCollectionId(ecologyHatchConf.getCollectionId());
            userEcologyReforgeUpperLimit.setUsableCount(reforgeCount);
            userEcologyReforgeUpperLimitList.add(userEcologyReforgeUpperLimit);
        }
        List<List<UserEcologyReforgeUpperLimit>> splitList = CollUtil.split(userEcologyReforgeUpperLimitList, 10000);
        for (List<UserEcologyReforgeUpperLimit> split : splitList) {
            userEcologyReforgeUpperLimitDao.saveList(split);
        }
        if (!CollectionUtils.isEmpty(temporarilyDTOList)) {
            List<List<TemporarilyDTO>> splitTemporarilyDTOList = CollUtil.split(temporarilyDTOList, 10000);
            for (List<TemporarilyDTO> split : splitTemporarilyDTOList) {
                userEcologyReforgeUpperLimitDao.saveTemporarilyDTOList(split);
            }
        }
        if (!CollectionUtils.isEmpty(userEcologyCastUpperLimitDetailsList)) {
            List<List<UserEcologyCastUpperLimitDetails>> splitUserEcologyCastUpperLimitDetailsList = CollUtil.split(userEcologyCastUpperLimitDetailsList, 10000);
            for (List<UserEcologyCastUpperLimitDetails> split : splitUserEcologyCastUpperLimitDetailsList) {
                userEcologyCastUpperLimitDetailsDao.saveList(split);
            }
        }
        if (!CollectionUtils.isEmpty(userEcologyReforgeUpperLimitDetailsList)) {
            List<List<UserEcologyReforgeUpperLimitDetails>> splitUserEcologyReforgeUpperLimitDetailsList = CollUtil.split(userEcologyReforgeUpperLimitDetailsList, 10000);
            for (List<UserEcologyReforgeUpperLimitDetails> split : splitUserEcologyReforgeUpperLimitDetailsList) {
                userEcologyReforgeUpperLimitDetailsDao.saveList(split);
            }
        }
    }

    /**
     * 熔炼记录消耗对应的藏品以及数量初始化 对应的脚本
     */
    @Override
    public void quantityInitialization(EcologyHatchConf ecologyHatchConf, Long methodId) {
        // 获取熔炼一份需要消耗的数量
        Integer expendCount = ecologyHatchConf.getExpendCount();
        // 获取熔炼一份需要消耗的销毁数量
        Integer destroyCount = ecologyHatchConf.getDestroyCount();
        // 获取所有的熔炼记录
        List<UserEcologyHatchRecords> userEcologyHatchRecordsList = userEcologyHatchRecordsDao.getList(ecologyHatchConf.getId());
        // 将熔炼记录根据用户ID进行区分
        Map<Long, List<UserEcologyHatchRecords>> userEcologyHatchRecordsMap = userEcologyHatchRecordsList.stream().collect(Collectors.groupingBy(UserEcologyHatchRecords::getUserId));
        // 生态铸造上限以及重铸上限以及兑换上限初始化
        upperLimitInitialization(ecologyHatchConf, userEcologyHatchRecordsMap);
        // 遍历
        List<UserEcologyCollectionRecords> userEcologyCollectionRecordsList = new ArrayList<>();

        for (Long userId : userEcologyHatchRecordsMap.keySet()) {
            List<UserEcologyHatchRecords> userEcologyHatchRecordList = userEcologyHatchRecordsMap.get(userId);
            for (UserEcologyHatchRecords userEcologyHatchRecords : userEcologyHatchRecordList) {
                // 添加熔炼消耗的藏品数量
                UserEcologyCollectionRecords userEcologyCollectionRecords = new UserEcologyCollectionRecords();
                userEcologyCollectionRecords.setUserId(userEcologyHatchRecords.getUserId());
                userEcologyCollectionRecords.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
                userEcologyCollectionRecords.setEcologyHatchId(userEcologyHatchRecords.getEcologyHatchId());
                userEcologyCollectionRecords.setCollectionId(userEcologyHatchRecords.getCollectionId());
                userEcologyCollectionRecords.setCollectionCount(expendCount * userEcologyHatchRecords.getHatchCount());
                userEcologyCollectionRecordsList.add(userEcologyCollectionRecords);
            }
        }
        List<List<UserEcologyCollectionRecords>> split = CollUtil.split(userEcologyCollectionRecordsList, 10000);
        for (List<UserEcologyCollectionRecords> userEcologyCollectionRecords : split) {
            userEcologyCollectionRecordsDao.saveList(userEcologyCollectionRecords);
        }
        // 熔炼方式添加到熔炼记录
        Assert.isTrue(userEcologyHatchRecordsDao.updateMethodByEcologyHatchId(ecologyHatchConf.getId(), methodId), () -> new GlobalRunTimeException("熔炼记录添加熔炼方法失败,熔炼配置ID:" + ecologyHatchConf.getId() + "方法ID:" + methodId));
    }

    /**
     * 用户生态孵化记录数据处理
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void userEcologyHatchRecordsDataProcessing(Long id) {
        // 查询出没有关联熔炼方式的生态熔炼配置
        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getNeedList(id).get(0);
        // 获取熔炼一份需要消耗的数量
        Integer expendCount = ecologyHatchConf.getExpendCount();
        // 获取熔炼一份需要消耗的销毁数量
        Integer destroyCount = ecologyHatchConf.getDestroyCount();
        // 回收数量
        Integer recycleCount = expendCount - destroyCount;
        // 获取所有的熔炼记录
        List<UserEcologyHatchRecords> userEcologyHatchRecordsList = userEcologyHatchRecordsDao.getList(ecologyHatchConf.getId());
        // 获取所有熔炼记录消耗的藏品记录
        // 回收
        List<UserEcologyHatchCollectionRecords> recycleList = userEcologyHatchCollectionRecordsDao.getList(ecologyHatchConf.getId(), UserEcologyHatchCollectionTypeRecordsEnum.RECYCLE);
        // 销毁
        List<UserEcologyHatchCollectionRecords> destroyList = userEcologyHatchCollectionRecordsDao.getList(ecologyHatchConf.getId(), UserEcologyHatchCollectionTypeRecordsEnum.DESTROY);

        // 将熔炼记录根据用户ID进行区分
        Map<Long, List<UserEcologyHatchRecords>> userEcologyHatchRecordsMap = userEcologyHatchRecordsList.stream().collect(Collectors.groupingBy(UserEcologyHatchRecords::getUserId));
        Map<Long, List<Long>> recycleMap = recycleList.stream().collect(Collectors.groupingBy(UserEcologyHatchCollectionRecords::getUserId, Collectors.mapping(UserEcologyHatchCollectionRecords::getId, Collectors.toList())));
        Map<Long, List<Long>> destroyMap = destroyList.stream().collect(Collectors.groupingBy(UserEcologyHatchCollectionRecords::getUserId, Collectors.mapping(UserEcologyHatchCollectionRecords::getId, Collectors.toList())));

        for (Long userId : userEcologyHatchRecordsMap.keySet()) {
            List<UserEcologyHatchRecords> userEcologyHatchRecordList = userEcologyHatchRecordsMap.get(userId);
            if (userEcologyHatchRecordList.size() > 2) {
                log.info("====================");
            }
            List<Long> userRecycleList = recycleMap.get(userId);
            List<Long> userDestroyList = destroyMap.get(userId);
            Integer recycleIndex = 0;
            Integer destroyIndex = 0;
            for (UserEcologyHatchRecords userEcologyHatchRecords : userEcologyHatchRecordList) {
                List<Long> needUpdateIds = new ArrayList<>();
                List<Long> needUpdateRecycleList = ListUtil.sub(userRecycleList, recycleIndex, recycleIndex + recycleCount * userEcologyHatchRecords.getHatchCount());
                List<Long> needUpdateDestroyList = ListUtil.sub(userDestroyList, destroyIndex, destroyIndex + destroyCount * userEcologyHatchRecords.getHatchCount());
                needUpdateIds.addAll(needUpdateRecycleList);
                if (!CollectionUtils.isEmpty(needUpdateDestroyList)) {
                    needUpdateIds.addAll(needUpdateDestroyList);
                }
                Assert.isTrue(userEcologyHatchCollectionRecordsDao.initialize(needUpdateIds, userEcologyHatchRecords.getId()), () -> new GlobalRunTimeException("用户-生态-孵化-藏品记录初始化失败 熔炼记录ID:" + userEcologyHatchRecords.getId()));
                recycleIndex = recycleIndex + recycleCount * userEcologyHatchRecords.getHatchCount();
                destroyIndex = destroyIndex + destroyCount * userEcologyHatchRecords.getHatchCount();

            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void script() {
        // 查询出8月1号之后熔炼的记录
        List<UserEcologyHatchRecords> scriptNeedList = userEcologyHatchRecordsDao.getScriptNeedList();
        List<Long> scriptNeedIdList = scriptNeedList.stream().map(userEcologyHatchRecords -> userEcologyHatchRecords.getId()).collect(Collectors.toList());
        // 获取熔炼记录对应的添加铸造数量
        List<UserEcologyCastUpperLimitDetails> userEcologyCastUpperLimitDetailsList = userEcologyCastUpperLimitDetailsDao.getByUserRecordsIds(scriptNeedIdList);
        Map<Long, UserEcologyCastUpperLimitDetails> userEcologyCastUpperLimitDetailsMap = userEcologyCastUpperLimitDetailsList.stream().collect(Collectors.toMap(UserEcologyCastUpperLimitDetails::getUserRecordsId, Function.identity()));

        // 获取熔炼记录对应的添加重铸数量
        List<UserEcologyReforgeUpperLimitDetails> userEcologyReforgeUpperLimitDetailsList = userEcologyReforgeUpperLimitDetailsDao.getByUserRecordsIds(scriptNeedIdList);
        Map<Long, UserEcologyReforgeUpperLimitDetails> userEcologyReforgeUpperLimitDetailsMap = userEcologyReforgeUpperLimitDetailsList.stream().collect(Collectors.toMap(UserEcologyReforgeUpperLimitDetails::getUserRecordsId, Function.identity()));


        Map<Long, List<UserEcologyHatchRecords>> scriptNeedMap =
                scriptNeedList.stream().collect(Collectors.groupingBy(UserEcologyHatchRecords::getEcologyHatchId));
        for (Long ecologyHatchId : scriptNeedMap.keySet()) {
            List<UserEcologyHatchRecords> userEcologyHatchRecords = scriptNeedMap.get(ecologyHatchId);
            EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(ecologyHatchId);
            // 用户对应熔炼记录
            Map<Long, List<UserEcologyHatchRecords>> userToUserEcologyHatchRecordsMap =
                    userEcologyHatchRecords.stream().collect(Collectors.groupingBy(UserEcologyHatchRecords::getUserId));
            for (Long userId : userToUserEcologyHatchRecordsMap.keySet()) {
                // 单个用户
                Integer addCastCount = 0;
                Integer addReforgeCount = 0;
                Integer castUseCount = 0;
                Integer reforgeUseCount = 0;
                List<UserEcologyHatchRecords> records = userToUserEcologyHatchRecordsMap.get(userId);
                for (UserEcologyHatchRecords userEcologyHatchRecord : records) {
                    // 计算出正确要添加的次数
                    addCastCount = addCastCount + ecologyHatchConf.getAddCastCount() * userEcologyHatchRecord.getHatchCount();
                    addReforgeCount = addReforgeCount + ecologyHatchConf.getAddReforgeCount() * userEcologyHatchRecord.getHatchCount();
                    // 获取对应的添加铸造次数和重铸次数的记录
                    // 铸造
                    UserEcologyCastUpperLimitDetails userEcologyCastUpperLimitDetails = userEcologyCastUpperLimitDetailsMap.get(userEcologyHatchRecord.getId());
                    if (Objects.nonNull(userEcologyCastUpperLimitDetails)) {
                        castUseCount =castUseCount + userEcologyCastUpperLimitDetails.getUseCount();
                    }
                    // 重铸
                    UserEcologyReforgeUpperLimitDetails userEcologyReforgeUpperLimitDetails = userEcologyReforgeUpperLimitDetailsMap.get(userEcologyHatchRecord.getId());
                    if (Objects.nonNull(userEcologyReforgeUpperLimitDetails)) {
                        // 判断要减少还是添加
                        reforgeUseCount = userEcologyReforgeUpperLimitDetails.getUseCount();
                    }
                }
                //获取用户的铸造上限
                UserEcologyCastUpperLimit userEcologyCastUpperLimit = userEcologyCastUpperLimitDao.getOneByUserIdAndCollectionId(userId, ecologyHatchConf.getCollectionId());
                if (Objects.isNull(userEcologyCastUpperLimit)){
                    userEcologyCastUpperLimit = new UserEcologyCastUpperLimit();
                    userEcologyCastUpperLimit.setUserId(userId);
                    userEcologyCastUpperLimit.setCollectionId(ecologyHatchConf.getCollectionId());
                    userEcologyCastUpperLimit.setUsableCount(0);
                    userEcologyCastUpperLimit.setExchangeCount(0);
                    userEcologyCastUpperLimit.insert();
                }
                if (castUseCount.intValue() > addCastCount.intValue()) {
                    // 数据库添加大于应该添加 减少
                    // 铸造上限调整记录
                    UserEcologyCastUpperLimitDetails newUserEcologyCastUpperLimitDetails = new UserEcologyCastUpperLimitDetails();
                    newUserEcologyCastUpperLimitDetails.setUserId(userId);
                    newUserEcologyCastUpperLimitDetails.setCollectionId(ecologyHatchConf.getCollectionId());
                    newUserEcologyCastUpperLimitDetails.setUserRecordsId(0L);
                    newUserEcologyCastUpperLimitDetails.setType(UserEcologyCastUpperLimitDetailsTypeEnum.SYS);
                    newUserEcologyCastUpperLimitDetails.setTypeName(UserEcologyCastUpperLimitDetailsTypeEnum.SYS.getDescription());
                    newUserEcologyCastUpperLimitDetails.setUseCount(castUseCount - addCastCount);
                    newUserEcologyCastUpperLimitDetails.setBeforeCount(userEcologyCastUpperLimit.getUsableCount());
                    newUserEcologyCastUpperLimitDetails.setAfterCount(userEcologyCastUpperLimit.getUsableCount() - newUserEcologyCastUpperLimitDetails.getUseCount());
                    newUserEcologyCastUpperLimitDetails.setIsAdd(Boolean.FALSE);
                    newUserEcologyCastUpperLimitDetails.insert();
                    Assert.isTrue(userEcologyCastUpperLimitDao.subNewCountByUserIdAndCollectionId(userId,ecologyHatchConf.getCollectionId()
                            ,newUserEcologyCastUpperLimitDetails.getUseCount(),userEcologyCastUpperLimit.getUsableCount()),() -> new GlobalRunTimeException("更新失败,数值不匹配"));

                } else if (castUseCount.intValue() < addCastCount.intValue()){
                    // 数据库添加小于应该添加 添加
                    UserEcologyCastUpperLimitDetails newUserEcologyCastUpperLimitDetails = new UserEcologyCastUpperLimitDetails();
                    newUserEcologyCastUpperLimitDetails.setUserId(userId);
                    newUserEcologyCastUpperLimitDetails.setCollectionId(ecologyHatchConf.getCollectionId());
                    newUserEcologyCastUpperLimitDetails.setUserRecordsId(0L);
                    newUserEcologyCastUpperLimitDetails.setType(UserEcologyCastUpperLimitDetailsTypeEnum.SYS);
                    newUserEcologyCastUpperLimitDetails.setTypeName(UserEcologyCastUpperLimitDetailsTypeEnum.SYS.getDescription());
                    newUserEcologyCastUpperLimitDetails.setUseCount(addCastCount - castUseCount);
                    newUserEcologyCastUpperLimitDetails.setBeforeCount(userEcologyCastUpperLimit.getUsableCount());
                    newUserEcologyCastUpperLimitDetails.setAfterCount(userEcologyCastUpperLimit.getUsableCount() + newUserEcologyCastUpperLimitDetails.getUseCount());
                    newUserEcologyCastUpperLimitDetails.setIsAdd(Boolean.TRUE);
                    newUserEcologyCastUpperLimitDetails.insert();
                    Assert.isTrue( userEcologyCastUpperLimitDao.addNewCountByUserIdAndCollectionId(userId,ecologyHatchConf.getCollectionId()
                            ,newUserEcologyCastUpperLimitDetails.getUseCount(),userEcologyCastUpperLimit.getUsableCount()),() -> new GlobalRunTimeException("更新失败,数值不匹配"));
                }

                UserEcologyReforgeUpperLimit userEcologyReforgeUpperLimit = userEcologyReforgeUpperLimitDao.getOneByUserIdAndCollectionId(userId, ecologyHatchConf.getCollectionId());
                if (Objects.isNull(userEcologyReforgeUpperLimit)){
                    userEcologyReforgeUpperLimit = new UserEcologyReforgeUpperLimit();
                    userEcologyReforgeUpperLimit.setUserId(userId);
                    userEcologyReforgeUpperLimit.setCollectionId(ecologyHatchConf.getCollectionId());
                    userEcologyReforgeUpperLimit.setUsableCount(0);
                    userEcologyReforgeUpperLimit.insert();
                }
                if (reforgeUseCount.intValue() > addReforgeCount.intValue()) {
                    // 数据库添加大于应该添加 减少
                    // 铸造上限调整记录
                    UserEcologyReforgeUpperLimitDetails newUserEcologyReforgeUpperLimitDetails = new UserEcologyReforgeUpperLimitDetails();
                    newUserEcologyReforgeUpperLimitDetails.setUserId(userId);
                    newUserEcologyReforgeUpperLimitDetails.setCollectionId(ecologyHatchConf.getCollectionId());
                    newUserEcologyReforgeUpperLimitDetails.setUserRecordsId(0L);
                    newUserEcologyReforgeUpperLimitDetails.setType(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS);
                    newUserEcologyReforgeUpperLimitDetails.setTypeName(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS.getDescription());
                    newUserEcologyReforgeUpperLimitDetails.setUseCount(reforgeUseCount - addReforgeCount);
                    newUserEcologyReforgeUpperLimitDetails.setBeforeCount(userEcologyReforgeUpperLimit.getUsableCount());
                    newUserEcologyReforgeUpperLimitDetails.setAfterCount(userEcologyReforgeUpperLimit.getUsableCount() - newUserEcologyReforgeUpperLimitDetails.getUseCount());
                    newUserEcologyReforgeUpperLimitDetails.setIsAdd(Boolean.FALSE);
                    newUserEcologyReforgeUpperLimitDetails.insert();
                    Assert.isTrue(userEcologyReforgeUpperLimitDao.subNewCountByUserIdAndCollectionId(userId,ecologyHatchConf.getCollectionId()
                            ,newUserEcologyReforgeUpperLimitDetails.getUseCount(),userEcologyReforgeUpperLimit.getUsableCount()),() -> new GlobalRunTimeException("更新失败,数值不匹配"));

                } else if (reforgeUseCount.intValue() < addReforgeCount.intValue()){
                    // 数据库添加小于应该添加 添加
                    UserEcologyReforgeUpperLimitDetails newUserEcologyReforgeUpperLimitDetails = new UserEcologyReforgeUpperLimitDetails();
                    newUserEcologyReforgeUpperLimitDetails.setUserId(userId);
                    newUserEcologyReforgeUpperLimitDetails.setCollectionId(ecologyHatchConf.getCollectionId());
                    newUserEcologyReforgeUpperLimitDetails.setUserRecordsId(0L);
                    newUserEcologyReforgeUpperLimitDetails.setType(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS);
                    newUserEcologyReforgeUpperLimitDetails.setTypeName(UserEcologyReforgeUpperLimitDetailsTypeEnum.SYS.getDescription());
                    newUserEcologyReforgeUpperLimitDetails.setUseCount(addReforgeCount - reforgeUseCount);
                    newUserEcologyReforgeUpperLimitDetails.setBeforeCount(userEcologyReforgeUpperLimit.getUsableCount());
                    newUserEcologyReforgeUpperLimitDetails.setAfterCount(userEcologyReforgeUpperLimit.getUsableCount() + newUserEcologyReforgeUpperLimitDetails.getUseCount());
                    newUserEcologyReforgeUpperLimitDetails.setIsAdd(Boolean.TRUE);
                    newUserEcologyReforgeUpperLimitDetails.insert();
                    Assert.isTrue( userEcologyReforgeUpperLimitDao.addNewCountByUserIdAndCollectionId(userId,ecologyHatchConf.getCollectionId()
                            ,newUserEcologyReforgeUpperLimitDetails.getUseCount(),userEcologyReforgeUpperLimit.getUsableCount()),() -> new GlobalRunTimeException("更新失败,数值不匹配"));
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void snapshotScript() {
//        List<EcologyHatchConf> ecologyHatchConfList = ecologyHatchConfDao.getScriptEcologyHatchConfList();
//        List<EcologyHatchRecordsRewards> ecologyHatchRecordsRewardsList = new ArrayList<>();
//        for (EcologyHatchConf ecologyHatchConf : ecologyHatchConfList) {
//            List<EcologyHatchRewardsConf> rewardsConfList = ecologyHatchRewardsConfDao.getListByEcologyHatchId(ecologyHatchConf.getId());
//            Map<Long, List<EcologyHatchRewardsConf>> rewardsConfMap = rewardsConfList.stream().collect(Collectors.groupingBy(EcologyHatchRewardsConf::getMethodId));
//            List<UserEcologyHatchRecords> userEcologyHatchRecordsList = userEcologyHatchRecordsDao.getList(ecologyHatchConf.getId());
//            for (UserEcologyHatchRecords userEcologyHatchRecords : userEcologyHatchRecordsList) {
//                List<EcologyHatchRewardsConf> ecologyHatchRewardsConfList = rewardsConfMap.get(userEcologyHatchRecords.getMethodId());
//                List<EcologyHatchRecordsRewards> ecologyHatchRecordsRewards = BeanUtil.copyToList(ecologyHatchRewardsConfList, EcologyHatchRecordsRewards.class);
//                for (EcologyHatchRecordsRewards ecologyHatchRecordsReward : ecologyHatchRecordsRewards) {
//                    ecologyHatchRecordsReward.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
//                }
//                ecologyHatchRecordsRewardsList.addAll(ecologyHatchRecordsRewards);
//            }
//        }
//        if (!CollectionUtils.isEmpty(ecologyHatchRecordsRewardsList)) {
//            List<List<EcologyHatchRecordsRewards>> splitUserEcologyReforgeUpperLimitDetailsList = CollUtil.split(ecologyHatchRecordsRewardsList, 10000);
//            for (List<EcologyHatchRecordsRewards> split : splitUserEcologyReforgeUpperLimitDetailsList) {
//                ecologyHatchRecordsRewardsDao.saveList(split);
//            }
//        }
    }

    @Override
    public void script638() {

    }


    @Override
    @Transactional
    public void releaseFrozenPoints() {
        List<ReleaseFrozenPointsDTO> releaseList = userEcologyPointsQuotaRecordsDao.releaseFrozenPoints();
        if (CollectionUtils.isEmpty(releaseList)) {
            return;
        }
        for (ReleaseFrozenPointsDTO release : releaseList) {
            Boolean points = userEcologyPointsService.addEcologyPoints(release.getUserId(), release.getAmount(), EcologyPointsEnum.SYSTEM_ADD, StrUtil.EMPTY);
            if (!points) {
                throw new GlobalRunTimeException("操作失败");
            }
        }
        Boolean flag = userEcologyPointsQuotaRecordsDao.removeAll();
        if (!flag) {
            throw new GlobalRunTimeException("操作失败.");
        }
    }
}
